// File:    funclist.cpp
// Author:  Brian Vanderburg II
// Purpose: Function list
//------------------------------------------------------------------------------


// Includes
#include <new>

#include "COMMON/expr/funclist.h"
#include "COMMON/expr/error.h"
#include "COMMON/expr/node.h"

namespace ExprEval
{

// Function factory
//------------------------------------------------------------------------------

// Constructor
FunctionFactory::FunctionFactory()
{}

// Destructor
FunctionFactory::~FunctionFactory()
{}

// Create
FunctionNode *FunctionFactory::Create (Expression *expr)
{
    FunctionNode *n = DoCreate (expr);
    if(n)
        n->m_factory = this;

    return n;
}


// Function list
//------------------------------------------------------------------------------

// Constructor
FunctionList::FunctionList()
{}

// Destructor
FunctionList::~FunctionList()
{
    // Free function factories
    Clear();
}

// Add factory to list
void FunctionList::Add (FunctionFactory *factory)
{
    // Check it
    if(factory == 0)
    {
        SHOW_FATAL_ERROR("Null Pointer of FunctionList::Add");
    }

    // Make sure it does not exist
    size_type pos;

    for (pos  = 0; pos < m_functions.size(); pos++)
    {
        if(m_functions[pos]->GetName() == factory->GetName())
        {
            SHOW_FATAL_ERROR("Already exists of " <<factory->GetName());
        }
    }

    m_functions.push_back(factory);
}

// Create a node for a function
FunctionNode *FunctionList::Create (const std::string &name, Expression *expr)
{
    // Make sure pointer exists
    if(expr == 0)
    {
        SHOW_FATAL_ERROR("Null Pointer of FunctionList::Create");
    }

    size_type pos;

    for (pos = 0; pos < m_functions.size(); pos++)
    {
        if(m_functions[pos]->GetName() == name)
        {
            // Found it
            return m_functions[pos]->Create (expr);
        }
    }

    // Not found
    return 0;
}

// FunctionList::AddDefaultFunctions is located in func.cpp
// along with the default function factories

// Free function list
void FunctionList::Clear()
{
    size_type pos;

    for (pos = 0; pos < m_functions.size(); pos++)
    {
        delete m_functions[pos];
    }
}

}
